package com.cjst.controller.sys;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;

import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.cjst.controller.base.BaseController;
import com.cjst.pojo.sys.SysDict;
import com.cjst.pojo.sys.SysOffice;
import com.cjst.pojo.sys.SysUser;
import com.cjst.sdp.util.MapUtils;
import com.cjst.sdp.util.ZTreeNode;
import com.cjst.service.sys.SysDictService;
import com.cjst.service.sys.SysOfficeService;
import com.cjst.sql.C;
import com.cjst.sql.Method;
import com.cjst.sql.WherePrams;
import com.cjst.util.json.ResultObj;

/**
 * 机构管理
 *
 * @author yj
 */
@Controller
@RequestMapping("/sys/sysOffice")
public class SysOfficeController extends BaseController {

    @Autowired
    private SysOfficeService officeService;
    @Autowired
    private SysDictService sysDictService;

    /**
     * 查询数据
     */
    @RequestMapping(value = "/list", method = RequestMethod.POST)
    @ResponseBody
    @RequiresPermissions("office")
    public Object list(String condition) {
        WherePrams wherePrams_dict = Method.where("pid", C.EQ, "0");
        wherePrams_dict.and("delFlag", C.EQ, "0");
        wherePrams_dict.and("type", C.EQ, "comp_type");
        SysDict dict = sysDictService.get(wherePrams_dict);
        List<SysDict> list = null;
        if (null != dict) {
            WherePrams param = Method.where("pid", C.EQ, dict.getId());
            param.and("type", C.EQ, "comp_type");
            param.and("delFlag", C.EQ, "0");
            list = sysDictService.list(param);
        }

        WherePrams wherePrams = Method.where("status", C.EQ, "1");
        if (StringUtils.isNotEmpty(condition)) {
            wherePrams.or("name", C.LIKE, condition, "1");
            wherePrams.or("enname", C.LIKE, condition, "1");
            wherePrams.or("compCode", C.LIKE, condition, "1");

        }
        wherePrams.orderBy("sort desc");
        
        List<SysOffice> offices = officeService.list(wherePrams);
        List<Map<String, Object>> maps = new ArrayList<>();
        if (offices != null && offices.size() > 0) {
            for (SysOffice office : offices) {
                Map<String, Object> officeMap = MapUtils.transBean2Map(office);
                String compType = office.getType();
                if (StringUtils.isNotEmpty(compType)) {            

                    if (null != list && list.size() > 0) {
                        for (SysDict d : list) {
                            if (d.getNum().equals(compType)) {
                                officeMap.put("compTypeName", d.getName());
                            }
                        }
                    }
                }
                String type = office.getType();
                if(type!=null) {
                	officeMap.put("typeVal", sysDictService.getDictVal("yes_no", type));
                }
                
                String fback = office.getFback();
                if(StringUtils.isNotEmpty(fback)) {
                	List<String> officeIds = Arrays.asList(fback.split(","));
                	String compnames = "";
                	for (int i = 0;i<officeIds.size();i++) {
                		SysOffice company = officeService.get(officeIds.get(i));
                    	if(company!=null) {
                    		compnames  = compnames+company.getName();
                    		if(i<officeIds.size()-1) {
                    			compnames+=",";
                    		}
                    	}
					}
                	officeMap.put("fbackVal", compnames);
                }
                
                
                maps.add(officeMap);

            }
        }
       return maps;

    }

    /**
     * 列表页面
     */
    @RequestMapping(value = "", method = RequestMethod.GET)
    @RequiresPermissions("office")
    public String toOffice() {
        return "system/office/office";
    }

    /**
     * 跳转到添加页面
     */
    @RequestMapping(value = "/add", method = RequestMethod.GET)
    @RequiresPermissions("office_add")
    public String addOffice(Model model) {
        WherePrams wherePrams = Method.where("pid", C.EQ, "0");
        wherePrams.and("delFlag", C.EQ, "0");
        wherePrams.and("type", C.EQ, "comp_type");
        SysDict dict = sysDictService.get(wherePrams);
        if (null != dict) {
            WherePrams param = Method.where("pid", C.EQ, dict.getId());
            param.and("type", C.EQ, "comp_type");
            param.and("delFlag", C.EQ, "0");
            List<SysDict> list = sysDictService.list(param);
            model.addAttribute("compTypes", list);
        }

        WherePrams wherePrams2 = Method.where("pid", C.EQ, "0");
        wherePrams2.and("delFlag", C.EQ, "0");
        wherePrams2.and("type", C.EQ, "comp_levels");
        SysDict dict2 = sysDictService.get(wherePrams2);
        if (null != dict2) {
            WherePrams param = Method.where("pid", C.EQ, dict2.getId());
            param.and("type", C.EQ, "comp_levels");
            param.and("delFlag", C.EQ, "0");
            param.orderBy("num asc");
            List<SysDict> list = sysDictService.list(param);
            model.addAttribute("compLevels", list);
        }
        
        //是否
  		List<Map<String, String>> yes_no = sysDictService.getDicts("yes_no");
  		if(yes_no!=null&&yes_no.size()>0) {
  			model.addAttribute("yes_no", yes_no);
  		}

        return "system/office/office_add";
    }

    /**
     * 机构详情页面
     * @param officeId
     * @param model
     * @return
     */
    @RequestMapping(value = "/toRelation/{officeId}", method = RequestMethod.GET)
    //@RequiresPermissions("office_add")
    public String vehicleOffice(@PathVariable String officeId, Model model) {
       
    	model.addAttribute("officeId", officeId);
        
        return "system/office/relation";
    }

    
    @RequestMapping(value = "/officeTreeList/{officeId}")
    @ResponseBody
    public List<ZTreeNode> officeTreeList(@PathVariable String officeId) throws Exception {
    	SysUser sysUser = (SysUser) SecurityUtils.getSubject().getPrincipal();
    	List<ZTreeNode> tree = officeService.tree(sysUser,"1"); //查看外勤公司
        
        SysOffice office = officeService.get(officeId);
        if(office!=null) {
        	String fback = office.getFback();
        	if(StringUtils.isNotEmpty(fback)) {
        		String[] offs = fback.split(",");
            	
            	List<String> offLst = Arrays.asList(offs);
            	for (ZTreeNode node : tree) {
    				node.setOpen(true);
            		String id = node.getId();
            		if(offLst.contains(id)) {
            			node.setChecked(true);
            		}else {
            			node.setChecked(false);
            		}
    			}
        	}else {
        		for (ZTreeNode node : tree) {
    				node.setOpen(true);           		
    			}
        	}
        }
        return tree;
    }
    
    @RequestMapping(value = "/setOutCompany", method = RequestMethod.POST)
    @ResponseBody
    @RequiresPermissions("office_relation")
    public Object relation(@RequestParam("officeId") String officeId, String ids) {
        if(StringUtils.isEmpty(officeId)) {
        	return new ResultObj(0, "参数传递错误", null);
        }
        
        SysOffice sysOffice = officeService.get(officeId);
        if(sysOffice == null) {
        	return new ResultObj(0, "机构不存在", null);
        }
        if("1".equals(sysOffice.getType())){
        	return new ResultObj(0, "外勤机构不允许关联外勤机构", null);
        }
        sysOffice.setFback(ids);
        officeService.update(sysOffice);
        return new ResultObj(1, "添加机构成功", null);
    }
    
    
    /**
     * 跳转到修改页面
     */
    @RequestMapping(value = "/update/{officeId}", method = RequestMethod.GET)
    @RequiresPermissions("office_update")
    public String updateOffice(@PathVariable String officeId, Model model) {
        WherePrams where = Method.where("id", C.EQ, officeId);
        SysOffice office = officeService.get(where);
        if (office != null) {
            Map<String, Object> officeMap = MapUtils.transBean2Map(office);
            //判断当前选择的节点是否顶层节点，如果不是，就查询上级节点
            if (office.getParentId() != null && !"0".equals(office.getParentId())) {
                WherePrams wherePrams = Method.where("id", C.EQ, office.getParentId());
                SysOffice pOffice = officeService.get(wherePrams);
                if (pOffice != null) {
                    officeMap.put("pName", pOffice.getName());
                }
            } else {
                officeMap.put("pName", "顶层");
            }
            
            if (office.getFback() != null && !"0".equals(office.getFback())) {
                WherePrams wherePrams = Method.where("id", C.EQ, office.getFback());
                SysOffice pOffice = officeService.get(wherePrams);
                if (pOffice != null) {
                    officeMap.put("companyName", pOffice.getName());
                }
            } else {
                officeMap.put("companyName", "顶层");
            }
            
            model.addAttribute("office", officeMap);
        }
        //model.addAttribute("compTypes", DictUtil.getDicts("comp_type"));

        WherePrams wherePrams = Method.where("pid", C.EQ, "0");
        wherePrams.and("delFlag", C.EQ, "0");
        wherePrams.and("type", C.EQ, "comp_type");
        SysDict dict = sysDictService.get(wherePrams);
        if (null != dict) {
            WherePrams param = Method.where("pid", C.EQ, dict.getId());
            param.and("type", C.EQ, "comp_type");
            param.and("delFlag", C.EQ, "0");
            List<SysDict> list = sysDictService.list(param);
            model.addAttribute("compTypes", list);
        }

        WherePrams wherePrams2 = Method.where("pid", C.EQ, "0");
        wherePrams2.and("delFlag", C.EQ, "0");
        wherePrams2.and("type", C.EQ, "comp_levels");
        SysDict dict2 = sysDictService.get(wherePrams2);
        if (null != dict2) {
            WherePrams param = Method.where("pid", C.EQ, dict2.getId());
            param.and("type", C.EQ, "comp_levels");
            param.and("delFlag", C.EQ, "0");
            param.orderBy("num asc");
            List<SysDict> list = sysDictService.list(param);
            model.addAttribute("compLevels", list);
        }
      //是否
  		List<Map<String, String>> yes_no = sysDictService.getDicts("yes_no");
  		if(yes_no!=null&&yes_no.size()>0) {
  			model.addAttribute("yes_no", yes_no);
  		}
        return "system/office/office_edit";
    }

    /**
     * 查看详情
     * @param officeId
     * @param model
     * @return
     */
    @RequestMapping(value = "/view/{officeId}", method = RequestMethod.GET)
    @RequiresPermissions("office_view")
    public String viewOffice(@PathVariable String officeId, Model model) {
        WherePrams where = Method.where("id", C.EQ, officeId);
        SysOffice office = officeService.get(where);
        if (office != null) {
            Map<String, Object> officeMap = MapUtils.transBean2Map(office);
            //判断当前选择的节点是否顶层节点，如果不是，就查询上级节点
            if (office.getParentId() != null && !"0".equals(office.getParentId())) {
                WherePrams wherePrams = Method.where("id", C.EQ, office.getParentId());
                SysOffice pOffice = officeService.get(wherePrams);
                if (pOffice != null) {
                    officeMap.put("pName", pOffice.getName());
                }
            } else {
                officeMap.put("pName", "顶层");
            }
            if (office.getFback() != null && !"0".equals(office.getFback())) {
                WherePrams wherePrams = Method.where("id", C.EQ, office.getFback());
                SysOffice pOffice = officeService.get(wherePrams);
                if (pOffice != null) {
                    officeMap.put("companyName", pOffice.getName());
                }
            } else {
                officeMap.put("companyName", "顶层");
            }
            model.addAttribute("office", officeMap);
        }
        //model.addAttribute("compTypes", DictUtil.getDicts("comp_type"));

        WherePrams wherePrams = Method.where("pid", C.EQ, "0");
        wherePrams.and("delFlag", C.EQ, "0");
        wherePrams.and("type", C.EQ, "comp_type");
        SysDict dict = sysDictService.get(wherePrams);
        if (null != dict) {
            WherePrams param = Method.where("pid", C.EQ, dict.getId());
            param.and("type", C.EQ, "comp_type");
            param.and("delFlag", C.EQ, "0");
            List<SysDict> list = sysDictService.list(param);
            model.addAttribute("compTypes", list);
        }
        //是否
  		List<Map<String, String>> yes_no = sysDictService.getDicts("yes_no");
  		if(yes_no!=null&&yes_no.size()>0) {
  			model.addAttribute("yes_no", yes_no);
  		}
        return "system/office/office_view";
    }


    /**
     * 保存添加
     */
    @RequestMapping(value = "/save/add", method = RequestMethod.POST)
    @ResponseBody
    @RequiresPermissions("office_add")
    public Object saveOffice(SysOffice office, HttpServletRequest req) {
        if(office == null) {
        	return new ResultObj(0, "参数传递错误，新增公司失败", null);
        }
        
        //上级公司
        String pid = office.getParentId();
        if(StringUtils.isEmpty(pid)) {
        	return new ResultObj(0, "参数【上级公司】未填写，新增部门失败", null);
        }
    	office.setStatus("1");
    	try {
    		 setParentIds(office);
		} catch (Exception e) {
			return new ResultObj(0, e.getMessage(), null);
		}
       
    	String id = officeService.addLocalByid(office);
        
        return new ResultObj(1, "添加机构成功", id);
    }


    
    
    /**
     * 保存修改
     */
    @RequestMapping(value = "/save/update", method = RequestMethod.POST)
    @ResponseBody
    @RequiresPermissions("office_update")
    public Object saveUpdate(SysOffice office){
    	if(office == null) {
        	return new ResultObj(0, "参数传递错误，新增公司失败", null);
        }
        
        //上级公司
        String pid = office.getParentId();
        if(StringUtils.isEmpty(pid)) {
        	return new ResultObj(0, "参数【上级公司】未填写，新增部门失败", null);
        }
        try {
   		    setParentIds(office);
		} catch (Exception e) {
			return new ResultObj(0, e.getMessage(), null);
		}
        
        int i =  officeService.updateLocal(office);
        
        return new ResultObj(1, "修改机构成功", i);
    }

    /**
     * 保存删除,逻辑删除，删除该节点及孩子节点
     */
    @RequestMapping(value = "/save/delete", method = RequestMethod.POST)
    @ResponseBody
    @RequiresPermissions("office_delete")
    public Object saveDelete(String officeId) {
    	if(StringUtils.isEmpty(officeId)) {
    		return new ResultObj(0, "参数传递错误，删除机构失败", null);
    	}
    	SysOffice office = officeService.get(officeId);
    	if(office == null) {
    		return new ResultObj(0, "机构不存在，删除失败", null);
    	}
    	
        WherePrams wherePrams = Method.where("id", C.EQ, officeId);
        wherePrams.or("parentIds", C.LIKE, officeId);
        SysOffice office2 = new SysOffice();
        office2.setStatus("0");
        officeService.updateLocal(office2, wherePrams);
        

        return new ResultObj(1, "删除成功", null);
    }

    /**
     * 获取机构的tree列表
     */
    @RequestMapping(value = "/tree/{type}", method = RequestMethod.POST)
    @ResponseBody
    public List<ZTreeNode> tree(@PathVariable String type) {
    	SysUser sysUser = (SysUser) SecurityUtils.getSubject().getPrincipal();
        List<ZTreeNode> tree = officeService.tree(sysUser,type);
        tree.add(ZTreeNode.createParent());
        return tree;
    }

    /**
     * 设置公司当前节点及下属节点的父pids
     * @param office
     * @throws Exception
     */
    private void setParentIds(@Valid SysOffice office) throws Exception {
        if (StringUtils.isEmpty(office.getParentId()) || office.getParentId().equals("0")) {
            office.setParentIds("0,");
        } else {
            String code = office.getParentId();
            WherePrams where = Method.where("id", C.EQ, code);
            SysOffice pOffice = officeService.get(where);
            if (pOffice != null) {
                if (StringUtils.isNotEmpty(office.getId())  && office.getId().equals(pOffice.getId())) {
                    throw new Exception("上级机构不能与当前机构相同");
                }
                if (StringUtils.isNotEmpty(office.getId())  && pOffice.getParentIds().contains(office.getId())) {
                    throw new Exception("上级机构不能是当前节点的子节点");
                }
                
                office.setParentIds(pOffice.getParentIds() + pOffice.getId() + ",");
            } else {
                throw new Exception("上级机构不存在");
            }
        }
        
        if(StringUtils.isNotEmpty(office.getId())) {
        	SysOffice office2 = officeService.get(office.getId());
            
            //检查当前节点下是否有孩子节点
            WherePrams prams = Method.where("status", C.EQ, "1");
            prams.and("parentIds", C.LIKE, office.getId());
            List<SysOffice> offices = officeService.list(prams);
            if(offices!=null&&offices.size()>0) {
            	for (SysOffice sysOffice : offices) {
    				//逐个遍历孩子节点，修改pids
            		String pids = sysOffice.getParentIds();
            		//修改后的节点为用当前节点的父节点，替换原有节点的父节点
            		//例如0，1, 2 原有父节点1，直属孩子的父节点是2，现将当前节点的父节点替换成0，则pids为0,2 
            		pids = office.getParentIds()+pids.substring(pids.indexOf(office2.getParentId())+office2.getParentId().length()+1);
            		
            		sysOffice.setParentIds(pids);
            		
            		officeService.updateLocal(sysOffice);
    			}
            }
        }
        
        
        
    }

    /**
     * 机构列表
     * @param req
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "/officeType", method = RequestMethod.POST)
    @ResponseBody
    public Object getOfficeList(HttpServletRequest req) throws Exception {
        WherePrams wherePrams = Method.where("status", C.EQ, "1");
        List<SysOffice> list = officeService.list(wherePrams);
        return list;
    }

}
